from typing import Optional, List
from datetime import datetime, date
from pydantic import BaseModel, EmailStr, Field
from enum import Enum


class GenderEnum(str, Enum):
    male = "male"
    female = "female" 
    other = "other"


class UserBase(BaseModel):
    username: str = Field(..., min_length=3, max_length=50, description="用户名")
    email: EmailStr = Field(..., description="邮箱地址")
    nickname: Optional[str] = Field(None, max_length=100, description="昵称")
    bio: Optional[str] = Field(None, description="个人简介")
    phone: Optional[str] = Field(None, max_length=20, description="手机号")
    gender: Optional[GenderEnum] = Field(None, description="性别")
    birthday: Optional[date] = Field(None, description="生日")
    location: Optional[str] = Field(None, max_length=100, description="所在地")


class UserRegister(BaseModel):
    username: str = Field(..., min_length=3, max_length=50, description="用户名")
    email: EmailStr = Field(..., description="邮箱地址")
    password: str = Field(..., min_length=6, max_length=50, description="密码")
    nickname: Optional[str] = Field(None, max_length=100, description="昵称")


class UserLogin(BaseModel):
    username: str = Field(..., description="用户名或邮箱")
    password: str = Field(..., description="密码")


class UserUpdate(BaseModel):
    nickname: Optional[str] = Field(None, max_length=100, description="昵称")
    bio: Optional[str] = Field(None, description="个人简介")
    phone: Optional[str] = Field(None, max_length=20, description="手机号")
    gender: Optional[GenderEnum] = Field(None, description="性别")
    birthday: Optional[date] = Field(None, description="生日")
    location: Optional[str] = Field(None, max_length=100, description="所在地")
    avatar: Optional[str] = Field(None, description="头像URL")


class UserPasswordChange(BaseModel):
    old_password: str = Field(..., description="旧密码")
    new_password: str = Field(..., min_length=6, max_length=50, description="新密码")


class UserPreferenceBase(BaseModel):
    favorite_avatar_id: Optional[int] = Field(None, description="喜欢的数字人ID")
    favorite_novels: Optional[List[int]] = Field(None, description="喜欢的小说列表")
    favorite_characters: Optional[List[int]] = Field(None, description="喜欢的角色列表")
    language: str = Field("zh-CN", description="语言偏好")
    theme: str = Field("light", description="主题偏好")
    voice_enabled: bool = Field(True, description="是否启用语音")
    voice_speed: float = Field(1.0, ge=0.5, le=3.0, description="语音播放速度")
    auto_play_voice: bool = Field(True, description="是否自动播放语音")
    notification_enabled: bool = Field(True, description="是否启用通知")


class UserPreferenceUpdate(UserPreferenceBase):
    pass


class UserPreference(UserPreferenceBase):
    id: int
    user_id: int
    created_at: datetime
    updated_at: Optional[datetime] = None
    
    class Config:
        from_attributes = True


class UserProfile(UserBase):
    id: int
    avatar: Optional[str] = None
    last_login_at: Optional[datetime] = None
    login_count: int = 0
    created_at: datetime
    updated_at: Optional[datetime] = None
    is_active: bool = True
    is_verified: bool = False
    preferences: Optional[UserPreference] = None
    
    class Config:
        from_attributes = True


class User(BaseModel):
    id: int
    username: str
    email: EmailStr
    nickname: Optional[str] = None
    avatar: Optional[str] = None
    bio: Optional[str] = None
    gender: Optional[GenderEnum] = None
    location: Optional[str] = None
    created_at: datetime
    is_active: bool = True
    is_verified: bool = False
    
    class Config:
        from_attributes = True


class UserInDB(UserProfile):
    password_hash: str


class Token(BaseModel):
    access_token: str
    refresh_token: str
    token_type: str = "bearer"
    expires_in: int


class TokenRefresh(BaseModel):
    refresh_token: str


class UserResponse(BaseModel):
    code: int = 200
    message: str = "操作成功"
    data: Optional[User] = None


class UserProfileResponse(BaseModel):
    code: int = 200
    message: str = "操作成功"
    data: Optional[UserProfile] = None


class TokenResponse(BaseModel):
    code: int = 200
    message: str = "登录成功"
    data: Optional[Token] = None


class ForgotPasswordRequest(BaseModel):
    email: EmailStr = Field(..., description="邮箱地址")
    captcha: str = Field(..., min_length=4, max_length=4, description="图形验证码")
    new_password: str = Field(..., min_length=6, max_length=50, description="新密码") 